// Copyright 2020 Poofee (https://github.com/Poofee)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
/*****************************************************************************
 *                                                                           *
 *  File:    material.cpp                                                    *
 *                                                                           *
 *****************************************************************************
 *                                                                           *
 *  Authors: Poofee                                                          *
 *  Email:   poofee@qq.com                                                   *
 *  Address: https://github.com/Poofee                                       *
 *  Date:    2020年07月15日                                                   *
 *                                                                           *
 *****************************************************************************/
#include "datatype.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define PI 3.14159265358979323846

CMaterial::CMaterial() {
    miu = 4.0*PI*1e-7;
	BHpoints = 0;
    Hdata = nullptr;
    Bdata = nullptr;
	H_c = 0;
	Theta_m = 0;
    Jr = 0;
    I = 0;
    tau = 0;
    sigma = 0;
    coil = nullptr;
    pm = nullptr;
}

CMaterial::~CMaterial() {
	if (Bdata != nullptr) {
		free(Bdata);
		Bdata = nullptr;
	}
	if (Hdata != nullptr) {
		free(Hdata);
		Hdata = nullptr;
	}
	if (coil != nullptr) {
		delete coil;
		coil = nullptr;
	}
	if (pm != nullptr) {
		delete pm;
		pm = nullptr;
	}
}


/**
 * @brief
 *
 * @param B
 * @return double
 */
double CMaterial::getMiu(double B) {
	double slope, H, b;
	if (BHpoints == 0) {
		return miu;
	} else {
		if (B < 1e-3)  return Bdata[1] / Hdata[1];
		getkHb(B, &slope, &H, &b);
	}
	if (B / H < PI*4e-7)  return PI * 4e-7;
	return B / H ;
}

/*!
 \brief 这里的处理仅仅使用了线性处理

 \param B
 \return double
*/
double CMaterial::getdvdB(double B) {
	double slope, H, b;
	if (BHpoints == 0 || B < 1e-9) return 0;
	getkHb(B, &slope, &H, &b);
	return -b / (B*B);
}


/**
 * @brief
 *
 * @param B
 * @param k
 * @param H
 * @param b
 */
void CMaterial::getkHb(double B, double * k, double * H, double * b) {
	
	if (B >= Bdata[BHpoints - 1]) {
		int  i = BHpoints - 2;
		(*k) = (Hdata[i] - Hdata[i - 1]) / (Bdata[i] - Bdata[i - 1]);
		(*b) = Hdata[i - 1] - (*k) * Bdata[i - 1];
	} else if (B < Bdata[0]) {
		(*k) = (Hdata[1] - Hdata[0]) / (Bdata[1] - Bdata[0]);
		(*b) = Hdata[0] - (*k) * Bdata[0];
	} else {
		for (int i = 0; i < BHpoints - 1; i++) {
			if (B >= Bdata[i] && B <= Bdata[i + 1]) {
				(*k) = (Hdata[i + 1] - Hdata[i]) / (Bdata[i + 1] - Bdata[i]);
				(*b) = Hdata[i] - (*k) * Bdata[i];
				break;
			}
		}
	}
	(*H) = (*k) * B + (*b);
}

/*!
 \brief 计算磁阻率对B2的偏导数
\begin{equation}
	\frac{  \partial \nu}{\partial \boldsymbol{B}^2}=\frac{  \partial \frac{H(B)}{B}}{\partial \boldsymbol{B}^2}=\frac{\partial \frac{kB+b}{B}}{\boldsymbol{B}^2}=-\frac{b}{2B^3}
\end{equation}
 \param B2
 \return double
*/
double CMaterial::getdvdB2(double B) {
	double slope, H, b;
	if (BHpoints == 0 || B < 1e-9) return 0;
	getkHb(B, &slope, &H, &b);
	return -b / (B * B * B * 2);
}
